Set

 

 

 

 

 

Set is a very useful concept in mathematics. Basically, Set is a type of collection that does not allow duplicate elements. That means an element can only exist once in a Set. The following picture illustrates three sets of numbers in mathematics: (see Figure 10.1).  

 

 

Figure 10.1. Abstraction of set in Mathematics

 

Like other collection objects set is also an important data structures and widely used to implement many logics in programming. Unlike other collection type such as array, list, linked list, set collection has the following distinctive characteristics.

 

·         Duplicate elements are not allowed.

·         Elements are not stored in order. That means you cannot expect elements sorted in any order when iterating over elements of a Set.

 

Set in Java Collection Framework

To realize Set collection, Java Collection framework supports a number of interfaces and classes which implements these interfaces (see Figure 10.2).

 Figure 10.2. Class hierarchy of Set

 

The Set interface

The Set interface defines a set. It extends Collection and specifies the behavior of a collection that does not allow duplicate elements. Therefore, the add( ) method returns false if an attempt is made to add duplicate elements to a set. It does not specify any additional methods of its own. Set is a generic interface that has this declaration:

 

interface Set<T>

 

Here, T specifies the type of objects that the set will hold.

 

The SortedSet interface

The SortedSet interface extends Set and declares the behavior of a set sorted in ascending order. SortedSet is a generic interface that has this declaration:

 

interface SortedSet<T>

 

Here, T specifies the type of objects that the set will hold.

 

In addition to those methods provided by Set, the SortedSet interface declares the methods summarized in Table 10.1.

 

Methods of SortedSet interface

Method

Description

Comparator<? super E> comparator( )

Returns the invoking sorted set’s comparator. If the natural ordering is used for this set, null is returned.

E first( )

Returns the first element in the invoking sorted set.

SortedSet<E> headSet(E end)

Returns a SortedSet containing those elements less than end that are contained in the invoking sorted set. Elements in the returned sorted set are also referenced by the invoking sorted set.

E last( )

Returns the last element in the invoking sorted set.

SortedSet<E> subSet(E start, E end)

Returns a SortedSet that includes those elements between start and end–1. Elements in the returned collection are also referenced by the invoking object.

SortedSet<E> tailSet(E start)

Returns a SortedSet that contains those elements greater than or equal to start that are contained in the sorted set. Elements in the returned set are also referenced by the invoking object.

Table 10.1: The methods declared by SortedSet interface

 

The NavigableSet interface

The NavigableSet interface extends SortedSet and declares the behavior of a collection that supports the retrieval of elements based on the closest match to a given value or values. NavigableSet is a generic interface that has this declaration:

interface NavigableSet<T>

 

Here, T specifies the type of objects that the set will hold. In addition to the methods that it inherits from SortedSet, NavigableSet adds those summarized in Table 10.2.

 

EnumSet class

EnumSet extends AbstractSet and implements Set. It is specifically for use with elements of an enum type. It is a generic class that has this declaration:

 

class EnumSet<E extends Enum<E>>

 

Here, E specifies the elements. Notice that E must extend Enum<E>, which enforces the requirement that the elements must be of the specified enum type.

 

EnumSet defines no constructors. Instead, it uses the factory methods shown in Table 3 to create objects.

 

The copyOf( ) and range( ) methods can also throw IllegalArgumentException. Notice that the of( ) method is overloaded a number of times. This is in the interest of efficiency. Passing a known number of arguments

can be faster than using a vararg parameter when the number of arguments is small.

 

Method

Description

static <E extends Enum<E>> EnumSet<E> allOf(Class<E> t)

Creates an EnumSet that contains the elements in the enumeration specified by t..

static <E extends Enum<E>> EnumSet<E>

complementOf(EnumSet<E> e)

Creates an EnumSet that is comprised of those elements not stored in e.

static <E extends Enum<E>>

EnumSet<E> copyOf(EnumSet<E> c)

Creates an EnumSet from the elements stored in c.

static <E extends Enum<E>>

EnumSet<E> copyOf(Collection<E> c)

Creates an EnumSet from the elements stored in c.

static <E extends Enum<E>>

EnumSet<E> noneOf(Class<E> t)

Creates an EnumSet that contains the elements that are not in the enumeration specified by t, which is an empty set by definition.

static <E extends Enum<E>>

EnumSet<E> of(E v, E … varargs)

Creates an EnumSet that contains v and zero or more additional enumeration values.

static <E extends Enum<E>>

EnumSet<E> of(E v)

Creates an EnumSet that contains v.

static <E extends Enum<E>>

EnumSet<E> of(E v1, E v2)

Creates an EnumSet that contains v1 and v2.

static <E extends Enum<E>>

EnumSet<E> of(E v1, E v2, E v3)

Creates an EnumSet that contains v1 through v3.

static <E extends Enum<E>>

EnumSet<E> of(E v1, E v2, E v3, E v4)

Creates an EnumSet that contains v1 through v4.

static <E extends Enum<E>>

EnumSet<E> of(E v1, E v2, E v3, E v4,

E v5)

Creates an EnumSet that contains v1 through v5.

static <E extends Enum<E>>

EnumSet<E> range(E start, E end)

Creates an EnumSet that contains the elements in the range specified by start and end.

Table 10.3: The methods defined by EnumSet class

Note:

·         All methods can throw NullPointerException.

·         The copyOf( ) and range( ) methods can also throw IllegalArgumentException.

·         The of( ) method is overloaded a number of times. This is in the interest of efficiency. Passing a known number of arguments can be faster than using a vararg parameter when the number of arguments is small.

 

Example 10.1 : Creating a set with collections of enumerated objects.

The following program illustrates the usage of a few basic methods s of EnumSet.

 

import java.util.EnumSet;

     

enum Color {RED, BLUE, GREEN, BLACK, WHITE, VIOLET, ORANGE, INDIGO};

 

public class EnumSetDemo {

    public static void main(String[] args)    {

        // Creating a set

        EnumSet<Color> set1, set2, set3, set4, set5, set6;

  

        // Adding elements

        set1 = EnumSet.of(Color.RED, Color.BLUE, Color.GREEN);

        set2 = EnumSet.complementOf(set1);

        set3 = EnumSet.allOf(Color.class);

        set4 = EnumSet.range(Color.BLACK, Color.VIOLET);

       set5 = EnumSet.copyOf(set2);

        set6 = EnumSet.noneOf(set1);

 

        System.out.println("Set 1: " + set1);

        System.out.println("Set 2: " + set2);

        System.out.println("Set 3: " + set3);

  System.out.println("Set 4: " + set4);

  System.out.println("Set4 contains RED? " + set4.contains(Color.RED);

 

 

  // Traversing elements

  Set5.forEach(System.out::println);

  //System.out.println("Set 5: " + set5);

 

 

    

        Iterator<Color> iter = set6.iterator(); 

        while (iter.hasNext()) 

             System.out.println(iter.next()); 

        }   

    }

}

 

Creating a Set

Set Interface in Java is present in java.util package. It extends the Collection interface. It represents the unordered set of elements which doesn't allow us to store the duplicate items. We can store a null element in Set.

 

Set can be implemented by anyone of the three classes:  HashSet, LinkedHashSet, and TreeSet.

 

HashSet<data-type> s1 = new HashSet<data-type>(); 

LinkedHashSet<data-type> s2 = new LinkedHashSet<data-type>(); 

TreeSet<data-type> s3 = new TreeSet<data-type>(); 

 

Alternative, you can use the following declaration as all of the class essentially implements Set interface.

 

Set<data-type> s1 = new HashSet<data-type>(); 

Set<data-type> s2 = new LinkedHashSet<data-type>(); 

Set<data-type> s3 = new TreeSet<data-type>(); 

 

Note:

·         Set being being a generic interface, it can contains object of any class, such as String, Integer, Person (a used defined class), etc.

·         Like an array, a particular set contains only homogeneous type of objects.

·         Unlike an array, it cannot include objects in duplicate.

 

In the following, you will learn how to create sets using the above-mentioned classes.

 

HashSet class

HashSet extends AbstractSet and implements the Set interface. It creates a collection that uses a hash table for storage. HashSet is a generic class that has this declaration:

 

class HashSet<E>

 

Here, E specifies the type of objects that the set will hold.

 

As most readers likely know, a hash table stores information by using a mechanism called hashing. In hashing, the informational content of a key is used to determine a unique value, called its hash code. The hash code is then used as the index at which the data associated with the key is stored. The transformation of the key into its hash code is performed automatically—you never see the hash code itself. Also, your code can’t directly index the hash table. The advantage of hashing is that it allows the execution time of add( ), contains( ), remove( ), and size( ) to remain constant even for large sets.

 

The following constructors are defined (see Table 10.4).

 

Constructor

Description

HashSet( )

It is a default constructor to create a hash set.

HashSet(Collection<? extends E> c)

It initializes the hash set by using the elements of c.

HashSet(int capacity)

It initializes the capacity of the hash set to capacity.

HashSet(int capacity, float fillRatio)

It initializes both the capacity and the fill ratio (also called load capacity ) of the hash set from its arguments. The fill ratio must be between 0.0 and 1.0, and it determines how full the hash set can be before it is resized upward.

Table 10.4: The constructors declared by HashSet class

Note:

Specifically, when the number of elements is greater than the capacity of the hash set multiplied by its fill ratio, the hash set is expanded. For constructors that do not take a fill ratio, 0.75 is used.

 

HashSet does not define any additional methods beyond those provided by its super classes and interfaces.

 

Example 10.2a: Creating a set with HashSet class

The following program demonstrates HashSet creation.

 

import java.util.*;

 

class HashSetCreateDemo {

public static void main(String args[]) {

// Create a hash set.

// HashSet<String> hs = new HashSet<String>();

// Set<String> hs = new HashSet<String>();

 

// Add elements to the hash set.

hs.add("India");

hs.add("Japan");

hs.add("Australia");

hs.add("Bangladesh");

hs.add("Pakistan");

hs.add("Nepal");

System.out.println(hs);

 

   }

}

 

 

 

Example 10.2b. Duplicate objects cannot be added into a set

The following program illustrates that if you add an object, which is already in the set, then that inclusion will be ignored automatically.

 

import java.util.HashSet;

import java.util.Set;

 

public class HashSetDuplicateDemo {

    public static void main(String[] args) {

        // Creating a HashSet

        Set<String> daysOfWeek = new HashSet<>();

 

        // Adding new elements to the HashSet

        daysOfWeek.add("Monday");

        daysOfWeek.add("Tuesday");

        daysOfWeek.add("Wednesday");

        daysOfWeek.add("Thursday");

        daysOfWeek.add("Friday");

        daysOfWeek.add("Saturday");

        daysOfWeek.add("Sunday");

 

        // Adding duplicate elements will be ignored

        daysOfWeek.add("Monday");

 

        System.out.println(daysOfWeek);

    }

}

 

Example 10.2c. A set can be created from any other collection

The following program illustrates how a set can be obtained from a collection.

 

import java.util.*;

 

class HashSetCollectionDemo {

public static void main(String args[]) {

 

//Creating a hash set from a collection

List<Integer> list = Arrays.asList(3, 9, 2, 4, 6, 2, 5, 3, 8, 9, 1, 7, 8, 6);

System.out.println(listNumbers);

 

HashSet<Integer> numSet = new HashSet<>(list);

System.out.println(numSet);

 

Set<Integers> bigSet = new HashSet<>(1000);

for(int i = 0; i < 1000, i++)

      bigSet.add(Math.Random());

System.out.printn(“If 555 is in the bigSet? “ + bigSet.contains(555));

   }

}

 

Note:

·         It is important to note that HashSet does not guarantee the order of its elements, because the process of hashing doesn’t usually lend itself to the creation of sorted sets.

·         You see, the list listNumbers contains duplicate numbers, and the set uniqueNumbers removes the duplicate ones.

·         The default, initial capacity of a HashSet is 16, so if you are sure that your Set contains more than 16 elements, it’s better to specify a capacity in the constructor.

 

Traversing a set

The following example shows different ways of iterating over a HashSet

 

·         Iterate over a HashSet using simple for-each loop.

·         Iterate over a HashSet using iterator().

·         Iterate over a HashSet using Java forEach and lambda expression.

·         Iterate over a HashSet using iterator() and  forEachRemaining() method.

 

Below is a simple example showing how to iterate over Java Set.

 

Example 10.3a: Traversing a set using Iterator

 

import java.util.*;

 

public class SetTraversalDemo {

    public static void main(String[] args) {

        Set<String> pLangs = new HashSet<>();

        pLangs.add("C");

        pLangs.add("C++");

        pLangs.add("Java");

        pLangs.add("Python");

        pLangs.add("PHP");

        pLangs.add("R");

 

  // Using simple for-each loop

        for(String pl: pLangs) {

            System.out.println(pl);

        }

 

 

  // Using iterator()

        Iterator<String> iter = pLangs.iterator();

        while (iter.hasNext()) {

            String pl = iter1.next();

            System.out.println(pl);

        }

 

 

  // Using forEach and lambda expression

        pLangs.forEach(pLangs -> { System.out.println(pLangs); });

 

 

  // Using iterator() and forEachRemaining() method 

  iter = pLangs.iterator();

        iter.forEachRemaining(pLangs -> { System.out.println(pLangs); });

       

    }

}

 

 

Example 10.3b: Iterating over a collection of type HashSet  using for-loop and forEach() method

The following program demonstrates a number of ways to traversing a HashSet collection.

 

import java.util.*;

 

class HashSetOperationDemo {

public static void main(String args[]) {

// Create a hash set.

Set<String> names = new HashSet<>();

names.add("Tom");

names.add("Mary");

names.add("Tom");

names.add("John");

names.add("Tom");

names.add("Bob");

names.add("Alice");

 

// Using a for loop

for (String name : names) {

    System.out.println(name);

}

 

// Uisng foreach method along with Lambda expression

names.forEach(System.out::println);

   }

}

 

Basic operations on a set

 

Example 10.4: Some basic operations with a collection of type HashSet

The following program demonstrates some basic operation on HashSet collection.

 

import java.util.*;

 

class HashSetOperationDemo {

public static void main(String args[]) {

// Create a hash set.

Set<String> names = new HashSet<>();

names.add("Tom");

names.add("Mary");

 

if (names.add("Peter")) {

            System.out.println("Peter is added to the set");

}

 

if (!names.add("Tom")) {

            System.out.println("Tom is already added to the set");

}

 

// Set can contain a null element

names.add(null);

 

// Removing elements from asset

if (names.remove("Mary")) {

    System.out.println("Marry is removed");

}

 

// Cointing the size of a set

System.out.printf("The set has %d elements", names.size());

 

// Check if set is empty

if (names.isEmpty()) {

    System.out.println("The set is empty");

} else {

    System.out.println("The set is not empty");

}

 

// Removing all elements from a set

names.clear();

   }

}

 

Note:

·         The add() method returns true if the set does not contain the specified element, and returns false if the set already contains the specified element.

·         The Set can contain a null element.

 

Example 10.5: Searching a collection of type HashSet

The following program demonstrates searching operation with a HashSet collection.

 

import java.util.*;

 

class HashSetOperationDemo {

public static void main(String args[]) {

// Create a hash set.

Set<String> names = new HashSet<>();

names.add("Tom");

names.add("Mary");

names.add("Tom");

names.add("John");

names.add("Tom");

names.add("Bob");

names.add("Alice");

 

if (names.contains("Mary")) {

            System.out.println("Found Mary");

}    

   }

}

 

Example 10.6: Basic Set Mathematics operations on a collection of type HashSet

The following program demonstrates searching operation with a HashSet collection.

 

import java.util.*;

 

class HashSetOperationDemo {

public static void main(String args[]) {

// Create a hash set.

Set<Integer> s1 = new HashSet<>(Arrays.asList(20, 56, 89, 31, 8, 5));

Set<Integer> s2 = new HashSet<>(Arrays.asList(8, 89));

 

// Sub set operation

if (s1.containsAll(s2)) {

    System.out.println("s2 is a subset of s1");

}

 

// Union operation

Set<Integer> s3 = new HashSet<>(Arrays.asList(1, 3, 5, 7, 9));

Set<Integer> s4 = new HashSet<>(Arrays.asList(2, 4, 6, 8));

 

System.out.println("s3 before union: " + s4);

S3.addAll(s4);

System.out.println("s3 after union: " + s4);

 

// Intersection operation

Set<Integer> s5 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 7, 9));

Set<Integer> s6 = new HashSet<>(Arrays.asList(2, 4, 6, 8));

 

System.out.println("s5 before intersection: " + s6);

s5.retainAll(s6);

System.out.println("s5 after intersection: " + s6);

 

// Set difference operation

Set<Integer> s7 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 7, 9));

Set<Integer> s8 = new HashSet<>(Arrays.asList(2, 4, 6, 8));

 

System.out.println("s7 before difference: " + s8);

s7.removeAll(s8);

System.out.println("s7 after difference: " + s8);

}    

   }

}

 

 

LinkedHashSet class

 

A LinkedHashSet is an ordered version of HashSet that maintains a doubly-linked List across all elements. When the iteration order is needed to be maintained this class is used. When iterating through a HashSet the order is unpredictable, while a LinkedHashSet lets us iterate through the elements in the order in which they were inserted. When cycling through LinkedHashSet using an iterator, the elements will be returned in the order in which they were inserted.

 

The LinkedHashSet class extends HashSet and adds no members of its own. It is a generic class that has this declaration:

 

class LinkedHashSet<E>

 

Here, E specifies the type of objects that the set will hold.

 

The constructors in the LinkedHashSet are shown in Table 10.5.

 

 

Constructor

Description

LinkedHashSet( )

It is a default constructor to create a hash set.

LinkedHashSet(Collection<? extends E> c)

It initializes the hash set by using the elements of c.

LinkedHashSet(int capacity)

It initializes the capacity of the hash set to capacity.

LinkedHashSet(int capacity, float fillRatio)

It initializes both the capacity and the fill ratio (also called load capacity ) of the linked hash set from its arguments. The fill ratio must be between 0.0 and 1.0, and it determines how full the linked hash set can be before it is resized upward.

Table 10.5: The constructors declared by LinkedHashSet class

Note:

·         The constructors in the LinkedHashSet class are in the similar form that of the constructor in Hashset class.

·         The LinkedHashSet class extends HashSet class and implements Set interface.

 

The LinkedHashSet class does not define any exclusive methods of its own. All methods are same as the methods as in HashSet class. This implies that whatever the operations we can prform with HashSet collections are also possible with the LinkedHashSet class. Hence, the manipulation of LinkedHashSet collections are not illustrated explicitly.

 

It is important to note that HashSet does not guarantee the order of its elements, because the process of hashing doesn’t usually lend itself to the creation of sorted sets. In contrast, the LinkdeHashSet follows the same order of the items as they are added into the set. For example, let us consider the creation of a set using both HashSet and LinkedHashset classes as shown Example 7.

 

Example 10.7: Difference between HashSet and LinkedHashSet collections.

The following program illustrates the ordering of elements in two sets created by Hashset and LinkedHashset classes.

 

import java.util.*;

 

class DifferentSetDemo {

public static void main(String args[]) {

// Create a hash set.

HashSet<String> hs = new HashSet<String>();

 

// Add elements to the hash set.

hs.add("A");

hs.add("B");

hs.add("C");

hs.add("D");

hs.add("E");

hs.add("F");

System.out.println(hs);

 

// Create a linked hash set.

LinkedHashSet<String> lhs = new LinkedHashSet<String>();

 

// Add elements to the hash set.

lhs.add("A");

lhs.add("B");

lhs.add("C");

lhs.add("D");

lhs.add("E");

lhs.add("F");

System.out.println(lhs);

      }

}

 

 

TreeSet class

 

TreeSet extends AbstractSet and implements the NavigableSet interface, which in turns successively extends SortedSet and Set interfaces. This implies all the methods defined in NavigableSet are implemented by the SortedSet class. It may be noted that this class like LinkedHashSet class does not have its own method defined.

 

The TreeSet It creates a collection that uses a tree for storage and hence its name. Further, in this type of set, elementss are stored in ascending order of sorting. Access and retrieval times are quite fast, which makes TreeSet an excellent choice when storing large amounts of sorted information that must be found quickly.  

 

The TreeSet class includes four constructors as summarized in Table 10.6.

 

Constructor

Description

TreeSet( )

It is a default constructor to create an empty set that will be sorted in ascending order according to the natural order of its elements.

TreeSet(Collection<? extends E> c)

It builds a tree set that contains the elements of c, where c is any collection.

TreeSet(Comparator<? super E> comp)

It creates an empty tree set that will be sorted according to the comparator specified by comp.

TreeSet(SortedSet<E> ss)

It builds a tree set that contains the elements of ss.

Table 10.6: Constructors in TreeSet class

Note:

·         In all cases, the capacity grows automatically as elements are added with set structure.

 

Example 10.8: Creating aTreeSet collections.

The following program illustrates the creating a tree sets created by TreeSet class.

 

import java.util.*;

 

class TreeSetDemo {

public static void main(String args[]) {

// Create a tree set.

TreeSet<String> ts = new TreeSet<String>();

 

// Add elements to the tree set.

ts.add("D");

ts.add("E");

ts.add("B");

ts.add("A");

ts.add("S");

ts.add("I");

ts.add("S");

System.out.println(ts);

}

}

 

Note:

·         As explained, because TreeSet stores its elements in a tree, they are automatically arranged in sorted order, as the output confirms.

 

Example 10.9: Programming with TreeSet collections.

Because TreeSet implements the NavigableSet interface, you can use the methods defined by NavigableSet to retrieve elements of a TreeSet. You can write many programs performing several operations with the method declared in NavigableSet. In the following, the application of subSet() is illustrated. The subSet() method returns a sub set of a tree set that contains the elements between elements, say e1 (inclusive) and e2 (exclusive).

 

import java.util.*;

 

class SubSetTreeSetDemo {

public static void main(String args[]) {

// Create a tree set.

TreeSet<String> ts = new TreeSet<String>();

 

// Add elements to the tree set.

ts.add("D");

ts.add("E");

ts.add("B");

ts.add("A");

ts.add("S");

ts.add("I");

ts.add("S");

System.out.println(ts.subSet(“D”, “S”);

}

}

 

 

Example 10.10: More using TreeSet

SortedSet is the alternate of Set interface that provides a total ordering on its elements. The elements of the SortedSet are arranged in the increasing (ascending) order. The SortedSet provides the additional methods that inhibit the natural ordering of the elements.

 

The SortedSet can be instantiated as:

 

 SortedSet<data-type> set = new TreeSet();  

 

Java TreeSet class implements the Set interface that uses a tree for storage. Like HashSet, TreeSet also contains unique elements. However, the access and retrieval time of TreeSet is quite fast. The elements in TreeSet stored in ascending order. Consider the following example:

 

import java.util.*;

public class SortedSetDemo {

  public static void main(String args[]) {

      int count[] = {34, 22,10,60,30,22};

      Set<Integer> set = new HashSet<Integer>();

      try {

         for(int i = 0; i < 5; i++) {

            set.add(count[i]);

         }

         System.out.println(set);

 

         TreeSet sortedSet = new TreeSet<Integer>(set);

         System.out.println("The sorted list is:");

         System.out.println(sortedSet);

 

         System.out.println("The First element of the set is: "+

                                                 (Integer)sortedSet.first());

         System.out.println("The last element of the set is: "+

                                                  (Integer)sortedSet.last());

      }

      catch(Exception e) {}

   }

}

 

Additional Illustrations with set collections

 

Example 10.11: Java Set to Stream

Below is a simple example showing how to convert a Java Set to Stream and perform some operations as per our requirements.

 

import java.util.*;

 

public class SetToStream {

 

   public static void main(String[] args) {

      Set<String> vowelsSet = new HashSet<>();

      // add example

      vowelsSet.add("a");

      vowelsSet.add("e");

      vowelsSet.add("i");

      vowelsSet.add("o");

      vowelsSet.add("u");

           

      //convert set to stream

      vowelsSet.stream().forEach(System.out::println);

   }

}

 

Copying an array to a set

Unlike List, We cannot convert a Java Set into an array directly as it’s NOT implemented using an Array. So We cannot use Arrays class to get the view of array as set. We can follow another approach. We can convert an array into List using Arrays.asList() method, then use it to create a Set. By using this approach, we can covert a Java Array to Set in two ways. Let us discuss them one by one using one simple example..

 

Example 10.12a: Approach 1

 In this approach, first We need to create a List using given array and use it to create a Set as shown below.

 

import java.util.*;

 

public class ArrayToSet {

   public static void main(String[] args) {

           

      String[] vowels = {"a","e","i","o","u"};

           

      Set<String> vowelsSet = new HashSet>(Arrays.asList(vowels));

      System.out.println(vowelsSet);

     

      /**

       * Unlike List, Set is NOt backed by array,

       * so we can do structural modification without any issues.

       */

      vowelsSet.remove("e");

      System.out.println(vowelsSet);

      vowelsSet.clear();

      System.out.println(vowelsSet);

   }

}

 

Example 10.12b: Approach 2

 In this approach, we do NOT use intermediate List to create a Set from an Array. First create an empty HashSet, then use Collections.addAll() to copy array elements into the given Set as shown below.

 

import java.util.*;

 

public class ArrayToSet2 {

   public static void main(String[] args) {

           

      String[] vowels = {"a","e","i","o","u"};

           

      Set<String> vowelsSet = new HashSet<>();

      Collections.addAll(vowelsSet, vowels);

      System.out.println(vowelsSet);

 

      /**

       * Unlike List, Set is NOt backed by array,

       * so we can do structural modification without any issues.

       */

      vowelsSet.remove("e");

      System.out.println(vowelsSet);

      vowelsSet.clear();

      System.out.println(vowelsSet);

   }

}

 

Creating a HashSet from another collection

 

Example 10.13:  A set from a collection

 The following program illustrates creation of asset from a colection.

 

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

public class CreateHashSetFromCollectionExample {

    public static void main(String[] args) {

        List<Integer> numbersDivisibleBy5 = new ArrayList<>();

        numbersDivisibleBy5.add(5);

        numbersDivisibleBy5.add(10);

        numbersDivisibleBy5.add(15);

        numbersDivisibleBy5.add(20);

        numbersDivisibleBy5.add(25);

 

        List<Integer> numbersDivisibleBy3 = new ArrayList<>();

        numbersDivisibleBy3.add(3);

        numbersDivisibleBy3.add(6);

        numbersDivisibleBy3.add(9);

        numbersDivisibleBy3.add(12);

        numbersDivisibleBy3.add(15);

 

        // Creating a HashSet from another collection (ArrayList)

        Set<Integer> numbersDivisibleBy5Or3 = new HashSet<>(numbersDivisibleBy5);

 

        // Adding all the elements from an existing collection to a HashSet

        numbersDivisibleBy5Or3.addAll(numbersDivisibleBy3);

 

        System.out.println(numbersDivisibleBy5Or3);

    }

}

 

Copying a set to an array

In this section, we will write a program to convert a Set of Strings into an Array of String using Set.toArray() method as shown below.

 

Example 10.14:

 

import java.util.*;

 

public class SetToArray {

   public static void main(String[] args) {

      Set<String< vowelsSet = new HashSet<>();

 

      // add example

      vowelsSet.add("a");

      vowelsSet.add("e");

      vowelsSet.add("i");

      vowelsSet.add("o");

      vowelsSet.add("u");

           

      //convert Set to Array

      String strArray[] = vowelsSet.toArray(new String[vowelsSet.size()]);

      System.out.println(Arrays.toString(strArray));

   }

}

 

Sorting a Set collection

As we know, Set (HashSet) does NOT support sorting elements directly. It stores and display it’s elements in random order. However, we have some approaches to sort it’s elements as shown below:

 

Example 10.15.

In this section, we will write a program to convert a Set of Strings into an Array of String using Set.toArray() method as shown below.

 

import java.util.*;

 

public class SetSortingExample {

 

      public static void main(String[] args) {

            Set<Integer> intsSet = new HashSet<>();

            Random random = new Random();

            for (int i = 0; i  {return (o2-o1);});

            System.out.println("Reverse Sorting: " + intsList2);

 

            // Approach-3

            Set<Integer> sortedSet = new TreeSet<>(intsSet);

            System.out.println("Sorted Set: " + sortedSet);

      }

}

 

Set collection using user defined objects

A queue in Java can grow automatically. The following program shows how a queue structure can be created with ArrayBlocking class (same as PriorotyQueue class) and insert elements and queue structure grows automatically.

 

Example 10.16.

 

import java.util.HashSet;

import java.util.Objects;

import java.util.Set;

 

class Customer {

    private long id;

    private String name;

 

    public Customer(long id, String name) {

        this.id = id;

        this.name = name;

    }

 

    public long getId() {

        return id;

    }

 

    public void setId(long id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    // Two customers are equal if their IDs are equal

    @Override

    public boolean equals(Object o) {

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        Customer customer = (Customer) o;

        return id == customer.id;

    }

 

    @Override

    public int hashCode() {

        return Objects.hash(id);

    }

 

    @Override

    public String toString() {

        return "Customer{" +

                "id=" + id +

                ", name='" + name + '\'' +

                '}';

    }

}

 

public class HashSetUserDefinedObjectExample {

    public static void main(String[] args) {

        Set<Customer> customers = new HashSet<>();

        customers.add(new Customer(101, "Rajeev"));

        customers.add(new Customer(102, "Sachin"));

        customers.add(new Customer(103, "Chris"));

 

        /*

          HashSet will use the `equals()` & `hashCode()` implementations

          of the Customer class to check for duplicates and ignore them

        */

        customers.add(new Customer(101, "Rajeev"));

 

        System.out.println(customers);

    }

}

 

--- * ---